﻿using System;
using System.Collections.Generic;
using System.Linq; 
using System.IO;
using NTTDATA.BEENChina.CaseMonitor.Base;
using NTTDATA.BEENChina.CaseMonitor.DAO;

namespace NTTDATA.BEENChina.CaseMonitor.CaseChecker
{
    public class DataCountChecker : BaseChecker
    {   
        private   string ConfigFile= "CaseCheckerConfig.xml";

        public DataCountChecker()
        {
         
        }
        
        public DataCountChecker(string configFile)
        {
          
            ConfigFile = configFile;
        }

        public int MonitorSpan
        {
            get;
            set;
        }
        
       

        public List<Note> Check()
        {   
            try
            {                    
                onProcessMessage("Instance CaseChecker");
                List<CaseChecker> checker = getObject();

                //给子节点补充customerid信息
                //子节点的customerid可以写可以不写
                //不写的时候用casechecker的
                checker = additionNotes(checker);

                List<Note> notes = checkDataCount(checker);

                onProcessMessage("Return caseChecker over");

                if (notes.Count > 0)
                {
                    onProcessMessage("Return caseChecker result");
                }

                return notes;
            }
            catch (Exception exp)
            {
                onProcessMessage("DataCountChecker Error");
                Log.Console.Error("DataCountChecker Error", exp);
            }
            return null;
        }

        private List<CaseChecker> additionNotes(List<CaseChecker> checker)
        {
            if (checker == null)
                return null;

            foreach (CaseChecker caseChecker in checker)
            {
                string customerid = caseChecker.CustomerID;

                if (!String.IsNullOrEmpty(customerid))
                {
                    List<Note> childs = caseChecker.NoteList;
                    additionNotes(ref childs, customerid);
                    caseChecker.NoteList = childs;
                }

            }
            return checker;
        }

         private void additionNotes(ref List<Note> notes,string customerid)
         {
             foreach (var note in notes)
             {
                 if (String.IsNullOrEmpty(note.CustomerID))
                 {
                     note.CustomerID = customerid;
                     List<Note> childs = note.NoteList;
                     additionNotes(ref childs, customerid);
                     note.NoteList = childs;
                 }
             }
         }

        private List<CaseChecker> getObject()
        {
            onProcessMessage("load config file");
            string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ConfigFile);

            if (!System.IO.File.Exists(filePath))
            {
                throw new FileNotFoundException(filePath);
            }

            onProcessMessage("Deserialize xml file");

            using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath))
            {
                System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(List<CaseChecker>));
                List<CaseChecker> obj = (List<CaseChecker>)xs.Deserialize(reader); 
                reader.Close();
                return obj;
            }
        }

        //public static void SerObject(string fileName, Object xmlobj)
        //{
        //    fileName = @"d:\\test.xml";
        //    using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
        //    {
        //        //得到被序列化的类型
        //        Type type = xmlobj.GetType();
        //        System.Xml.Serialization.XmlSerializer sz = new System.Xml.Serialization.XmlSerializer(type);
        //        //开始序列化
        //        sz.Serialize(stream, xmlobj);
        //        object o = sz.Deserialize(stream);
        //    }
        //}

        private List<Note> checkDataCount(List<CaseChecker> checkerlist)
        {
            if (checkerlist == null)
            {
                throw new ArgumentNullException("checkCaseDataCount,parameter:checkerlist");
            }

            onProcessMessage("checking DataCount...");
            List<Note> ret = new List<Note>();
            foreach (CaseChecker checker in checkerlist)
            {
                checkCaseDataCount(checker, ret); 
            }

            return ret;
        }

        private List<Note> checkCaseDataCount(CaseChecker checker,List<Note> ret)
        {
            if (checker == null)
            {
                throw new ArgumentNullException("checkDataCount,parameter:checker");
            }
            if (ret == null)
            {
                throw new ArgumentNullException("checkDataCount,parameter:ret");
            }

            if (!isMonitorTime(checker))
            {
                return ret;
            }

            foreach (Note note in checker.NoteList)
            {
               
                checkNoteDataCount(note,  ret);
            }
            return  ret;
        }

        private bool isMonitorTime(CaseChecker checker)
        {

            if (checker == null)
            {
                throw new ArgumentNullException("isMonitorTime,parameter:checker");
            }
            
            if (string.IsNullOrEmpty(checker.MonitorTime))
            {
                return false;
            }


            string[] settingTime = checker.MonitorTime.Split(new char[] { ':' });
            if (settingTime == null || settingTime.Length < 2)
            {
                throw new Exception("MonitorTime is error");
            }

            DateTime todayMonitorTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,
                int.Parse(settingTime[0]), int.Parse(settingTime[1]), 0);
            //DateTime yesterdayMonitorTime = todayMonitorTime.AddDays(-1);
            DateTime lastRunTime = CaseDBAccesser.GetLastRunTime(checker.CaseID);

            if ((DateTime.Now.CompareTo(todayMonitorTime) > 0  &&  lastRunTime.CompareTo (todayMonitorTime )< 0) ||
                (DateTime.Now.CompareTo(todayMonitorTime) > 0  && lastRunTime.CompareTo(DateTime.MaxValue) ==0 ) )
            {
                CaseDBAccesser.InsertRunLog(checker.CaseID, DateTime.Now);
                return true;
            }
            else
            {
                return false ;
            }

            //if (checkTime.CompareTo(monitorTime) <= 0 &&
            //    checkTime.AddMinutes(MonitorSpan).CompareTo(monitorTime) > 0)
            //{
            //    return true;
            //}
            //return false;
        }

        private void checkNoteDataCount(Note note,List<Note> ret)
        {
            if (note == null)
            {
                throw new ArgumentNullException("checkNoteDataCount,parameter:note");
            }
            if (note.NoteList == null || note.NoteList.Count == 0)
            {
                return;
            }

            int parentCount = note.GetDataCount();
            int childCount = getChildDataCount(note);
            if(parentCount != childCount )
            {
                ret.Add(note);
            }

            onProcessMessage(string.Format("server:{0} {1}", note.Name, note.GetDataCount()));

            foreach (Note child in note.NoteList)
            {
                onProcessMessage(string.Format("server:{0} {1}", child.Name,child.GetDataCount()));
                checkNoteDataCount(child, ret);
            }
        }
        
        private int getChildDataCount(Note note)
        {
            if (note.NoteList == null)
            {
                return 0;
            }

            int sum = note.NoteList.Sum(o => o.GetDataCount());
            return sum;
        }

       

    }
}